package com.bubble.base.common.base;

import com.alibaba.fastjson.JSON;
import com.bubble.base.common.exception.BizException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

public class BaseController {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    protected HttpServletRequest request;

    @Autowired
    protected HttpServletResponse response;

    /** 视图前缀 */
    protected String viewPrefix;

    public BaseController() {
        setViewPrefix(defaultViewPrefix());
    }

    /**
     * 统一异常处理
     */
    @ExceptionHandler(Exception.class)
    public ModelAndView handleException(Exception e, HttpServletRequest request, HttpServletResponse response) {

        Map<String, Object> map = new HashMap<String, Object>();
        try {
            //设置跨域请求
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "*");
            response.setHeader("Access-Control-Max-Age", "3628800");
            response.setContentType("application/json;charset=utf-8");

            PrintWriter out = null;
            try {
                out = response.getWriter();
                if (e instanceof BizException) {
                    response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
                    map.put("status", response.getStatus());
                    map.put("message", e.getMessage());
                    out.print(JSON.toJSONString(map));
                } else if(e instanceof com.alibaba.dubbo.rpc.RpcException) {
                    response.setStatus(HttpStatus.SERVICE_UNAVAILABLE.value());
                    map.put("status", response.getStatus());
                    map.put("message", "服务不可用，或已下架，请联系管理员。");
                    out.print(JSON.toJSONString(map));
                } else if(e instanceof NullPointerException) {
                    response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
                    map.put("status", response.getStatus());
                    map.put("message", "空指针异常");
                    out.print(JSON.toJSONString(map));
                } else {
                    response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
                    map.put("status", response.getStatus());
                    map.put("message", e.getMessage());
                    out.print(JSON.toJSONString(map));
                }

            } catch (IOException ioEx) {
                ioEx.printStackTrace();
            } finally {
                out.flush();
                out.close();
            }
            return null;
        } finally {
            logger.error("Web异常拦截："+map.get("message"), e);
        }
    }


    /**
     * 获取Controller注解上的路径
     * @return
     */
    protected String defaultViewPrefix() {
        String currentViewPrefix = "";
        RequestMapping requestMapping = AnnotationUtils.findAnnotation(getClass(), RequestMapping.class);
        if (requestMapping != null && requestMapping.value().length > 0) {
            currentViewPrefix = requestMapping.value()[0];
        }
        return currentViewPrefix;
    }

    /**
     * 设置视图名称
     * @param suffixName
     * @return
     */
    public String viewName(String suffixName) {
        if (!suffixName.startsWith("/")) {
            suffixName = "/" + suffixName;
        }
        return getViewPrefix() + suffixName;
    }

    /**
     * 设置视图前缀
     * @param viewPrefix
     */
    public void setViewPrefix(String viewPrefix) {
        if (viewPrefix.startsWith("/")) {
            viewPrefix = viewPrefix.substring(1);
        }
        this.viewPrefix = viewPrefix;
    }

    public String getViewPrefix() {
        return viewPrefix;
    }

}
